package com.lyl.activiti.demo.web.controller;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.lyl.activiti.demo.bean.Leave;
import com.lyl.activiti.demo.bpm.cmd.HistoryProcessInstanceDiagramCmd;
import com.lyl.activiti.demo.bpm.cmd.WithdrawTaskCmd;
import com.lyl.activiti.demo.mapper.CustomMapper;
import com.lyl.activiti.demo.mapper.LeaveMapper;

/**
 * 
 * @author lijj
 * 
 */
@Controller
@RequestMapping(value = "/huiqian")
public class HuiQianController extends BaseController {
	@Autowired
	LeaveMapper leaveMapper;
	@Autowired
	CustomMapper customMapper;
	private static final String HUIQIAN_PROCESS_DEFINITION_KEY = "huiQianSubprocess2";

	/**
	 * 流程列表
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/processList")
	public String processList(Model model) {
		ProcessDefinitionQuery processDefinitionQuery = repositoryService
				.createProcessDefinitionQuery();
		List<ProcessDefinition> list = processDefinitionQuery.latestVersion()
				.processDefinitionKey(HUIQIAN_PROCESS_DEFINITION_KEY)
				.orderByProcessDefinitionId().asc().list();
		model.addAttribute("processList", list);
		return "/huiqian/processList";
	}

	/**
	 * 开启流程（huiQian和huiQianSubprocess）
	 * 
	 * @return
	 */
	/*
	 * @RequestMapping("startProcess") public String startProcess(Leave leave,
	 * HttpSession session) { String userId = ((User)
	 * session.getAttribute("user")).getId(); leave.setApplyUserId(userId);
	 * leaveMapper.insert(leave); // 启动流程的用户信息
	 * identityService.setAuthenticatedUserId(userId); List<User> users =
	 * identityService.createUserQuery().list(); Map<String, Object> vars = new
	 * HashMap<String, Object>(); List<String> countersignUsers = new
	 * ArrayList<String>(); for (User user : users) {
	 * countersignUsers.add(user.getFirstName()); } vars.put("countersignUsers",
	 * countersignUsers); vars.put("businesskey",
	 * String.valueOf(leave.getId())); runtimeService.startProcessInstanceByKey(
	 * HUIQIAN_PROCESS_DEFINITION_KEY, vars);
	 * 
	 * return "redirect:/huiqian/processList"; }
	 */

	/**
	 * 启动流程(huiQianSubprocess2)
	 * 
	 * @param leave
	 * @param session
	 * @return
	 */
	@RequestMapping("startProcess")
	public String startProcess(Leave leave, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		leave.setApplyUserId(userId);
		leaveMapper.insert(leave);
		// 启动流程的用户信息
		identityService.setAuthenticatedUserId(userId);
		// List<User> users = identityService.createUserQuery().list();
		Map<String, Object> vars = new HashMap<String, Object>();
		List<String> countersignUsers = new ArrayList<String>();
		countersignUsers.add("lily");
		countersignUsers.add("lucy");
		// for (User user : users) {
		// countersignUsers.add(user.getFirstName());
		// }
		vars.put("countersignUsers", countersignUsers);
		vars.put("businesskey", String.valueOf(leave.getId()));
		runtimeService.startProcessInstanceByKey(
				HUIQIAN_PROCESS_DEFINITION_KEY, vars);

		return "redirect:/huiqian/processList";
	}

	/**
	 * 输出图片
	 * 
	 * @param processDefinitionId
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping("/processDefinitionImage/{processDefinitionId}")
	public void getProcessDefinitionImage(
			@PathVariable("processDefinitionId") String processDefinitionId,
			HttpServletResponse response) throws IOException {
		ProcessDefinition processDefinition = repositoryService
				.createProcessDefinitionQuery()
				.processDefinitionId(processDefinitionId).singleResult();
		InputStream inputStream = repositoryService.getResourceAsStream(
				processDefinition.getDeploymentId(),
				processDefinition.getDiagramResourceName());
		byte[] b = new byte[1024];
		int len = -1;
		while ((len = inputStream.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}

	/**
	 * 待办任务列表
	 * 
	 * @return
	 */
	@RequestMapping("/toDoProcessList")
	public String userToDoProcessList(Model model, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		// 获取当前用户为候选人的任务
		// 获取已经分配给当前用户的任务
		List<Task> tasks = taskService.createTaskQuery()
				.processDefinitionKey(HUIQIAN_PROCESS_DEFINITION_KEY)
				.taskCandidateUser(userId).list();
		List<Task> task2 = taskService.createTaskQuery()
				.processDefinitionKey(HUIQIAN_PROCESS_DEFINITION_KEY)
				.taskAssignee(userId).list();
		tasks.addAll(task2);
		model.addAttribute("tasks", tasks);

		// 根据待办中的processInstanceId获得ProcessInstance ProcessDefinition
		HashMap<String, HistoricProcessInstance> historicProcessInstances = new HashMap<String, HistoricProcessInstance>();
		HashMap<String, ProcessDefinition> processDefinitions = new HashMap<String, ProcessDefinition>();
		for (Task task : tasks) {
			ProcessDefinition processDefinition = repositoryService
					.createProcessDefinitionQuery()
					.processDefinitionId(task.getProcessDefinitionId())
					.singleResult();
			processDefinitions.put(task.getProcessDefinitionId(),
					processDefinition);

			HistoricProcessInstance historicProcessInstance = historyService
					.createHistoricProcessInstanceQuery()
					.processInstanceId(task.getProcessInstanceId())
					.singleResult();
			historicProcessInstances.put(task.getProcessInstanceId(),
					historicProcessInstance);
		}
		model.addAttribute("historicProcessInstances", historicProcessInstances);
		model.addAttribute("processDefinitions", processDefinitions);
		return "/huiqian/toDoProcessList";
	}

	/**
	 * 签收流程
	 * 
	 * @param taskId
	 * @param session
	 * @return
	 */
	@RequestMapping("/claimProcess")
	public String claimProcess(String taskId, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		taskService.claim(taskId, userId);
		return "redirect:/huiqian/toDoProcessList";
	}

	/**
	 * 获取任务表单
	 * 
	 * @param taskDefinitionKey
	 * @param taskId
	 * @param processInstanceId
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/getTaskForm/{taskDefinitionKey}/{taskId}/{processInstanceId}")
	public String getTaskForm(
			@PathVariable("taskDefinitionKey") String taskDefinitionKey,
			@PathVariable("taskId") String taskId,
			@PathVariable("processInstanceId") String processInstanceId,
			Model model) throws Exception {
		ProcessInstance processInstance = runtimeService
				.createProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult();
		// List<HistoricVariableInstance> historicVariableInstances =
		// historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list();
		// for (HistoricVariableInstance historicVariableInstance :
		// historicVariableInstances) {
		// if("countersignUsers".equals(historicVariableInstance.getVariableName())){
		// List<String> countersignUsers = (List<String>)
		// historicVariableInstance.getValue();
		// for (String string : countersignUsers) {
		// System.out.println("@@@"+string);
		// }
		// }
		// }
		HistoricVariableInstance historicVariableInstance = historyService
				.createHistoricVariableInstanceQuery()
				.processInstanceId(processInstanceId)
				.variableName("businesskey").singleResult();

		Leave leave = leaveMapper.selectByPrimaryKey(Integer
				.parseInt((String) historicVariableInstance.getValue()));
		model.addAttribute("leave", leave);
		model.addAttribute("taskId", taskId);

		// if ("managerApprove".equals(taskDefinitionKey)) {
		// return "/huiqian/managerApprove";
		// } else if ("modifyApply".equals(taskDefinitionKey)) {
		// return "/huiqian/modifyApply";
		// } else if ("reportBack".equals(taskDefinitionKey)) {
		// return "/huiqian/reportBack";
		// }
		return "/huiqian/managerApprove";
	}

	/**
	 * 完成经理审批
	 * 
	 * @param leave
	 * @param deptLeaderPass
	 * @param taskId
	 * @param session
	 * @return
	 */
	@RequestMapping("/completeTaskManagerApprove")
	@ResponseBody
	public String completeTaskManagerApprove(Leave leave,
			@RequestParam("deptLeaderPass") String deptLeaderPass,
			@RequestParam("taskId") String taskId, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		String processInstanceId = taskService.createTaskQuery().taskId(taskId)
				.singleResult().getProcessInstanceId();
		String taskName = taskService.createTaskQuery().taskId(taskId)
				.singleResult().getName();
		leaveMapper.updateByPrimaryKeySelective(leave);
		Map<String, String> formProperties = new HashMap<String, String>();
		formProperties.put("deptLeaderPass", deptLeaderPass);
		try {
			identityService.setAuthenticatedUserId(userId);
			formService.submitTaskFormData(taskId, formProperties);
		} finally {
			identityService.setAuthenticatedUserId(null);
		}

		/*
		 * // 开启流程后，设置会签人员（huiQian和huiQianSubprocess） if (taskName.equals("请假"))
		 * { List<Task> list = taskService.createTaskQuery()
		 * .processInstanceId(processInstanceId).taskName("审核").list();
		 * List<HistoricVariableInstance> historicVariableInstance =
		 * historyService .createHistoricVariableInstanceQuery()
		 * .processInstanceId(processInstanceId)
		 * .variableName("countersignUser").list(); List<String>
		 * countersignUser=new ArrayList<String>(); for
		 * (HistoricVariableInstance historicVariableInstance2 :
		 * historicVariableInstance) { countersignUser.add((String)
		 * historicVariableInstance2.getValue()); } int i = 0; for (Task task2 :
		 * list) { // task2.setAssignee(countersignUser.get(i));
		 * taskService.setAssignee(task2.getId(), countersignUser.get(i)); i++;
		 * } }
		 */
		// 开启流程后，设置会签人员（huiQian和huiQianSubprocess）
		if (taskName.equals("审核")) {
			List<Task> list = taskService.createTaskQuery()
					.processInstanceId(processInstanceId).taskName("一审").list();
			List<HistoricVariableInstance> historicVariableInstance = historyService
					.createHistoricVariableInstanceQuery()
					.processInstanceId(processInstanceId)
					.variableName("countersignUser").list();
			List<String> countersignUser = new ArrayList<String>();
			for (HistoricVariableInstance historicVariableInstance2 : historicVariableInstance) {
				countersignUser.add((String) historicVariableInstance2
						.getValue());
			}
			int i = 0;
			for (Task task2 : list) {
				// task2.setAssignee(countersignUser.get(i));
				taskService.setAssignee(task2.getId(), countersignUser.get(i));
				i++;
			}
		}
		// 判断一审是否完成（若已完成，则一定会生成二审任务）
		List<Task> list = taskService.createTaskQuery()
				.processInstanceId(processInstanceId).taskName("二审").list();

		if (list != null && list.size() > 0 && !taskName.equals("二审")) {
			List<HistoricTaskInstance> historyTasks = historyService
					.createHistoricTaskInstanceQuery()
					.processInstanceId(processInstanceId).taskName("一审").list();
			List<String> countersignUser = new ArrayList<String>();
			for (HistoricTaskInstance historicVariableInstance2 : historyTasks) {
				countersignUser.add(historicVariableInstance2.getAssignee());
			}
			int i = 0;
			for (Task task2 : list) {
				// task2.setAssignee(countersignUser.get(i));
				taskService.setAssignee(task2.getId(), countersignUser.get(i));
				i++;
			}
		}

		return "true";
	}

	/**
	 * 已办任务
	 * 
	 * @param model
	 * @param session
	 * @return
	 */
	@RequestMapping("/processedTaskList")
	public String processedTaskList(Model model, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		List<HistoricTaskInstance> processedTasks = historyService
				.createHistoricTaskInstanceQuery().taskAssignee(userId)
				.finished().list();
		model.addAttribute("processedTasks", processedTasks);
		HashMap<String, HistoricProcessInstance> processInstances = new HashMap<String, HistoricProcessInstance>();
		for (HistoricTaskInstance historicTaskInstance : processedTasks) {
			HistoricProcessInstance historicProcessInstance = historyService
					.createHistoricProcessInstanceQuery()
					.processInstanceId(
							historicTaskInstance.getProcessInstanceId())
					.singleResult();
			processInstances.put(historicTaskInstance.getProcessInstanceId(),
					historicProcessInstance);
		}
		model.addAttribute("processInstances", processInstances);
		return "/huiqian/processedTaskList";
	}

	/**
	 * 获取当前流程实例的流程图
	 * 
	 * @param processInstanceId
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping("/image/{processInstanceId}")
	public void getImage(
			@PathVariable("processInstanceId") String processInstanceId,
			HttpServletResponse response) throws Exception {
		Command<InputStream> cmd = new HistoryProcessInstanceDiagramCmd(
				processInstanceId);
		InputStream in = managementService.executeCommand(cmd);
		response.setContentType("image/png");
		byte[] b = new byte[1024];
		int len = -1;
		while ((len = in.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}

	/**
	 * 显示流程图例子
	 */
//	public InputStream getDiagram(String processInstanceId) {
//		ProcessInstance pi = runtimeService
//				.createProcessInstanceQuery()
//				.processInstanceId(processInstanceId).singleResult();
//		RepositoryServiceImpl rs=(RepositoryServiceImpl) repositoryService;
//		ProcessDefinitionEntity pd = (ProcessDefinitionEntity)rs.getDeployedProcessDefinition(
//				pi.getProcessDefinitionId());
//		InputStream is = ProcessDiagramGenerator.generateDiagram(pd, "png", 
//				runtimeService.getActiveActivityIds(processInstanceId));		
//		return is;
//	}
//	private byte[] getImgByte(InputStream is) throws IOException{
//		ByteArrayOutputStream bytestream=new ByteArrayOutputStream();
//		int b;
//		while((b=is.read())!=-1){
//			bytestream.write(b);
//		}
//		byte[] bs=bytestream.toByteArray();
//		bytestream.close();
//		return bs;
//	}

	/**
	 * 撤销已办任务
	 * 
	 * @param taskId
	 * @return
	 */
	@RequestMapping("/callBack/{taskId}")
	@ResponseBody
	public String callBack(@PathVariable("taskId") String taskId) {
		Command<Integer> cmd = new WithdrawTaskCmd(taskId);
		return managementService.executeCommand(cmd).toString();
	}

	/**
	 * 完成修改申请
	 * 
	 * @param leave
	 * @param reApply
	 * @param taskId
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/completeTaskModifyApply")
	public String completeTaskModifyApply(Leave leave,
			@RequestParam("reApply") String reApply,
			@RequestParam("taskId") String taskId, HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		// 更新leave表
		leaveMapper.updateByPrimaryKeySelective(leave);

		Map<String, String> formProperties = new HashMap<String, String>();
		formProperties.put("reApply", reApply);
		try {
			identityService.setAuthenticatedUserId(userId);
			formService.submitTaskFormData(taskId, formProperties);
		} finally {
			identityService.setAuthenticatedUserId(null);
		}
		return "/huiqian/processList";
	}

	/**
	 * 销假
	 * 
	 * @param taskId
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/completeTaskReportBack")
	public String completeTaskReportBack(@RequestParam("taskId") String taskId,
			HttpSession session) {
		String userId = ((User) session.getAttribute("user")).getId();
		try {
			identityService.setAuthenticatedUserId(userId);
			taskService.complete(taskId);
		} finally {
			identityService.setAuthenticatedUserId(null);
		}
		return "/huiqian/processList";
	}

}
